﻿// MedicalRulesEngine.Infrastructure/Repositories/RuleRepository.cs
using Microsoft.EntityFrameworkCore;
using MedicalRulesEngine.Domain.Entities;
using MedicalRulesEngine.Infrastructure.Data;
using System.Text.Json;

namespace MedicalRulesEngine.Infrastructure.Repositories;

/// <summary>
/// 规则仓储实现
/// 提供规则相关的数据访问操作
/// </summary>
public class RuleRepository : Repository<MetadataRule>, IRuleRepository
{
    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="context">数据库上下文</param>
    public RuleRepository(RulesDbContext context) : base(context)
    {
    }

    /// <summary>
    /// 根据工作流名称获取规则
    /// </summary>
    /// <param name="workflowName">工作流名称</param>
    /// <returns>规则集合</returns>
    public async Task<IEnumerable<MetadataRule>> GetByWorkflowAsync(string workflowName)
    {
        return await _dbSet
            .Include(r => r.Conditions)
            .Include(r => r.Actions)
            .Include(r => r.Tags)
            .Where(r => r.WorkflowName == workflowName)
            .OrderBy(r => r.Priority)
            .ThenBy(r => r.Name)
            .ToListAsync();
    }

    /// <summary>
    /// 根据分类获取规则
    /// </summary>
    /// <param name="category">分类</param>
    /// <returns>规则集合</returns>
    public async Task<IEnumerable<MetadataRule>> GetByCategoryAsync(string category)
    {
        return await _dbSet
            .Include(r => r.Tags)
            .Where(r => r.Category == category)
            .OrderBy(r => r.Priority)
            .ThenBy(r => r.Name)
            .ToListAsync();
    }

    /// <summary>
    /// 获取启用的规则
    /// </summary>
    /// <returns>启用的规则集合</returns>
    public async Task<IEnumerable<MetadataRule>> GetEnabledRulesAsync()
    {
        return await _dbSet
            .Include(r => r.Conditions)
            .Include(r => r.Actions)
            .Include(r => r.Tags)
            .Where(r => r.IsEnabled && r.Status == RuleStatus.Published)
            .OrderBy(r => r.Priority)
            .ThenBy(r => r.Name)
            .ToListAsync();
    }

    /// <summary>
    /// 根据规则代码获取规则
    /// </summary>
    /// <param name="code">规则代码</param>
    /// <returns>规则对象</returns>
    public async Task<MetadataRule?> GetByCodeAsync(string code)
    {
        return await _dbSet
            .Include(r => r.Conditions)
            .Include(r => r.Actions)
            .Include(r => r.Tags)
            .FirstOrDefaultAsync(r => r.Code == code);
    }

    /// <summary>
    /// 获取规则及其完整信息（包含条件、动作、标签）
    /// </summary>
    /// <param name="id">规则ID</param>
    /// <returns>完整的规则对象</returns>
    public async Task<MetadataRule?> GetWithDetailsAsync(string id)
    {
        return await _dbSet
            .Include(r => r.Conditions.OrderBy(c => c.Order))
                .ThenInclude(c => c.ChildConditions)
            .Include(r => r.Actions.OrderBy(a => a.Order))
            .Include(r => r.Tags)
            .FirstOrDefaultAsync(r => r.Id == id);
    }

    /// <summary>
    /// 搜索规则
    /// </summary>
    /// <param name="searchTerm">搜索词</param>
    /// <param name="category">分类过滤</param>
    /// <param name="isEnabled">启用状态过滤</param>
    /// <returns>符合条件的规则集合</returns>
    public async Task<IEnumerable<MetadataRule>> SearchRulesAsync(string? searchTerm = null,
        string? category = null, bool? isEnabled = null)
    {
        var query = _dbSet.Include(r => r.Tags).AsQueryable();

        // 应用搜索条件
        if (!string.IsNullOrWhiteSpace(searchTerm))
        {
            query = query.Where(r =>
                r.Name.Contains(searchTerm) ||
                r.Code.Contains(searchTerm) ||
                r.Description!.Contains(searchTerm));
        }

        // 应用分类过滤
        if (!string.IsNullOrWhiteSpace(category))
        {
            query = query.Where(r => r.Category == category);
        }

        // 应用启用状态过滤
        if (isEnabled.HasValue)
        {
            query = query.Where(r => r.IsEnabled == isEnabled.Value);
        }

        return await query
            .OrderBy(r => r.Priority)
            .ThenBy(r => r.Name)
            .ToListAsync();
    }

    /// <summary>
    /// 复制规则
    /// </summary>
    /// <param name="sourceRuleId">源规则ID</param>
    /// <param name="newName">新规则名称</param>
    /// <param name="newCode">新规则代码</param>
    /// <returns>复制后的规则</returns>
    public async Task<MetadataRule> CloneRuleAsync(string sourceRuleId, string newName, string newCode)
    {
        // 获取源规则及其完整信息
        var sourceRule = await GetWithDetailsAsync(sourceRuleId);
        if (sourceRule == null)
        {
            throw new ArgumentException($"未找到ID为 {sourceRuleId} 的规则", nameof(sourceRuleId));
        }

        // 创建新规则
        var clonedRule = new MetadataRule
        {
            Id = Guid.NewGuid().ToString(),
            Name = newName,
            Code = newCode,
            Description = sourceRule.Description,
            WorkflowName = sourceRule.WorkflowName,
            Category = sourceRule.Category,
            SubCategory = sourceRule.SubCategory,
            Priority = sourceRule.Priority,
            IsEnabled = false, // 复制的规则默认为禁用状态
            Expression = sourceRule.Expression,
            MetadataJson = sourceRule.MetadataJson,
            Status = RuleStatus.Draft,
            CreatedAt = DateTime.UtcNow,
            CreatedBy = sourceRule.CreatedBy
        };

        // 复制条件
        foreach (var condition in sourceRule.Conditions)
        {
            var clonedCondition = new RuleCondition
            {
                Id = Guid.NewGuid().ToString(),
                RuleId = clonedRule.Id,
                FieldPath = condition.FieldPath,
                Operator = condition.Operator,
                Value = condition.Value,
                LogicalOperator = condition.LogicalOperator,
                Order = condition.Order,
                MetadataJson = condition.MetadataJson,
                GroupName = condition.GroupName
            };
            clonedRule.Conditions.Add(clonedCondition);
        }

        // 复制动作
        foreach (var action in sourceRule.Actions)
        {
            var clonedAction = new RuleAction
            {
                Id = Guid.NewGuid().ToString(),
                RuleId = clonedRule.Id,
                Name = action.Name,
                ActionType = action.ActionType,
                ConfigJson = action.ConfigJson,
                Order = action.Order,
                IsEnabled = action.IsEnabled
            };
            clonedRule.Actions.Add(clonedAction);
        }

        // 复制标签
        foreach (var tag in sourceRule.Tags)
        {
            var clonedTag = new RuleTag
            {
                Id = Guid.NewGuid().ToString(),
                RuleId = clonedRule.Id,
                Name = tag.Name,
                Value = tag.Value,
                Color = tag.Color
            };
            clonedRule.Tags.Add(clonedTag);
        }

        // 保存到数据库
        await _dbSet.AddAsync(clonedRule);
        await _context.SaveChangesAsync();

        return clonedRule;
    }
}

